package com.nofeng.wx.job;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.nofeng.wx.controller.stock.view.TodayResultView;
import com.nofeng.wx.controller.stock.view.template.WxGzhVolumeData;
import com.nofeng.wx.service.FindStockService;
import com.nofeng.wx.service.StockService;
import com.nofeng.wx.service.WxGzhService;
import com.nofeng.wx.service.stock.BacktestResult;
import com.nofeng.wx.service.stock.DailyStockData;
import com.nofeng.wx.service.stock.StockInfo;
import com.nofeng.wx.third.EastMoneyStockApi;
import com.nofeng.wx.third.FinanceHttpApi;
import com.nofeng.wx.third.NocodeDbApi;
import com.nofeng.wx.third.WeixinApi;
import com.nofeng.wx.utils.BaseUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Component
public class StockJob {

    @Autowired
    StockService stockService;
    @Autowired
    WeixinApi weixinApi;
    @Autowired
    FindStockService findStockService;
    @Autowired
    WxGzhService wxGzhService;

//    @Scheduled(cron = "0 45 9 * * ?")
//    public void defaultCacheJob() {
//        biz();
//    }
//
    @Scheduled(cron = "0 20 14 * * ?")
    public void todayJob() {
        stockService.refreshWg();
    }
    @Scheduled(cron = "0 25 14 * * ?")
    public void todayJob_saveStrongStock() {
        findStockService.saveStrongStock();
        findStockService.refresh();
    }
    @Scheduled(cron = "0 20 11 * * ?")
    public void wx() {
        try {
            wxGzhService.today();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @Scheduled(cron = "0 0 10 * * ?")
    public void todayJob2() {
        stockService.refreshWg();
        findStockService.refresh();
    }
    @Scheduled(cron = "0 10 10 * * ?")
    public void todayJob3() {
        biz();
    }
//
//    @Scheduled(cron = "0 20 14 * * ?")
//    public void afternoonTodayJob() {
//        today();
//    }

    @Scheduled(cron = "0 25 14 * * ?")
    public void afternoon() {
        biz();
    }


    public void today() {

    }



    public void biz() {
        try {

            LocalDate today = LocalDate.now(); // 获取当前日期
            if (today.getDayOfWeek() == DayOfWeek.SATURDAY || today.getDayOfWeek() == DayOfWeek.SUNDAY) {
                return;
            }

            ArrayList<WxGzhVolumeData> inVolumeDataList = Lists.newArrayList();
            ArrayList<WxGzhVolumeData> outVolumeDataList = Lists.newArrayList();
            JSONArray hotIndustry = EastMoneyStockApi.getHotIndustry(1);
            for (int i = 0; i < hotIndustry.size(); i++) {
                JSONObject industryJSON = hotIndustry.getJSONObject(i);
                String name = industryJSON.getString("f14");
                String vol = industryJSON.getString("f62");
                double volValue = BaseUtils.stringToBigDecimal(vol).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() / 100000000;
                if (volValue > 12) {
                    WxGzhVolumeData inVolume = new WxGzhVolumeData();
                    inVolume.setName(name);
                    inVolume.setVolumeFmt((int) Math.round(volValue));
                    inVolumeDataList.add(inVolume);
                }
            }
            for (int i = hotIndustry.size() - 1; i >= hotIndustry.size() - 10; i--) {
                JSONObject industryJSON = hotIndustry.getJSONObject(i);
                String name = industryJSON.getString("f14");
                String vol = industryJSON.getString("f62");
                double volValue = BaseUtils.stringToBigDecimal(vol).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() / 100000000;
                if (volValue < -12) {
                    WxGzhVolumeData outVolume = new WxGzhVolumeData();
                    outVolume.setName(name);
                    outVolume.setVolumeFmt((int) Math.round(volValue));
                    outVolumeDataList.add(outVolume);
                }
            }


            DailyStockData sz = stockService.sz();
            DailyStockData ssz = stockService.ssz();
            BigDecimal volumeMoney=sz.getVolumeMoney().add(ssz.getVolumeMoney());
            BigDecimal volumeMoneyYi = volumeMoney.divide(new BigDecimal("100000000"), 2, RoundingMode.HALF_UP);
            Map<String, Integer> count = Maps.newHashMap();
            try {
                count = EastMoneyStockApi.getCount();
            } catch (IOException e) {
                e.printStackTrace();
            }
            double up_count_ratio = new BigDecimal(count.get("up")).doubleValue() / new BigDecimal(count.get("down") + count.get("up")).doubleValue();

            String br = "</br>";
            String msg = "量化策略" + br+br;

            String ETF=WxGzhService.ETF+",510300";
            String RED="601398,600406,600309,300059,600900,000333,601318,600941,601390,600036,600377,601088";
            String ATT="002371,002594,300760,002475,002230,688981,688041,688008,603986,688256";
            boolean push = false;

            msg +="今日成交："+volumeMoneyYi.doubleValue()+"亿"+br;
            msg +="今日涨跌比："+BaseUtils.doubleToPtStr(up_count_ratio)+br;

            if(CollectionUtils.isNotEmpty(inVolumeDataList)) {
                msg +=br+br;
                msg +="今日流入："+br;
                for (WxGzhVolumeData wxGzhVolumeData : inVolumeDataList) {
                    msg +=wxGzhVolumeData.getName()+",流入"+wxGzhVolumeData.getVolumeFmt()+"亿"+br;
                }
            }
            if(CollectionUtils.isNotEmpty(outVolumeDataList)) {
                msg +=br+br;
                msg +="今日流出："+br;
                for (WxGzhVolumeData wxGzhVolumeData : outVolumeDataList) {
                    msg +=wxGzhVolumeData.getName()+",流出"+wxGzhVolumeData.getVolumeFmt()+"亿"+br;
                }
            }

            msg +=br;
            Pair<Boolean, String> etfPair = buildMessage( ETF,"ETF:");
            if(etfPair.getKey()){
                push=true;
                msg+=etfPair.getRight();
            }
            Pair<Boolean, String> redPair = buildMessage(RED,"红利:");
            if(redPair.getKey()){
                push=true;
                msg+=redPair.getRight();
            }

            Pair<Boolean, String> attPair = buildMessage( ATT,"进攻:");
            if(attPair.getKey()){
                push=true;
                msg+=attPair.getRight();
            }

            if (push) {
                weixinApi.push(msg);
            } else {
               weixinApi.push("量化策略:无需操作,耐心持有");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public  FinanceHttpApi.HttpStockData getStock(String code){
        String stock = stockService.stock(code, false);
        JSONObject stockJSON = JSONObject.parseObject(stock);
        Double atr60 = stockJSON.getDouble("atr60");
        FinanceHttpApi.HttpStockData stockInfo = stockJSON.getObject("stock", FinanceHttpApi.HttpStockData.class);
        stockInfo.setAtr60(atr60);
        double atr60Chp = atr60 / stockInfo.getClose().doubleValue()*100;
        stockInfo.setAtr60Chp(atr60Chp);
        stockInfo.setCutPrice(stockInfo.getMa14().subtract(new BigDecimal(atr60)));
        stockInfo.setPrePrice(stockInfo.getPrePrice());
        return stockInfo;
    }

    public Pair<Boolean,String> buildMessage(String target,String title) {
        StringBuilder msg= new StringBuilder();
        String br = "</br>";
        msg.append(title).append(br);
        Boolean push=false;
        List<FinanceHttpApi.HttpStockData> etfDataList= Lists.newArrayList();
        List<FinanceHttpApi.HttpStockData> sellList=Lists.newArrayList();
        List<FinanceHttpApi.HttpStockData> buyList=Lists.newArrayList();
        for (String code : StringUtils.split(target, ",")) {
            FinanceHttpApi.HttpStockData stock = getStock(code);
            if(null!=stock){
                etfDataList.add(stock);
            }
        }
        Collections.sort(etfDataList, (o1, o2) -> o1.getRsi().compareTo(o2.getRsi()));
        for (FinanceHttpApi.HttpStockData httpStockData : etfDataList) {
            if(httpStockData.getPrePrice().doubleValue()>=httpStockData.getCutPrice().doubleValue()
                    && httpStockData.getClose().doubleValue()<httpStockData.getCutPrice().doubleValue()){
                sellList.add(httpStockData);
            }
            double buyPrice = httpStockData.getCutPrice().doubleValue()+httpStockData.getAtr60();
            if(httpStockData.getPrePrice().doubleValue()<= buyPrice
                    && httpStockData.getClose().doubleValue()>=buyPrice){
                buyList.add(httpStockData);
            }
        }
        for (FinanceHttpApi.HttpStockData  buy : buyList) {
                long optCount = calcOptCount(buy);
                msg.append(String.format("【买】%s,%s。数量：%d,止损:%s", buy.getStockCode(), buy.getStockName(), optCount,buy.getCutPrice().setScale(3,BigDecimal.ROUND_HALF_UP).toString()));
                msg.append(br);
                push =true;

        }
        for (FinanceHttpApi.HttpStockData  sell : sellList) {
            long optCount = calcOptCount(sell);
            msg.append(String.format("【卖】%s,%s。数量：%d", sell.getStockCode(), sell.getStockName(), optCount));
            msg.append(br);
            push =true;

        }
        msg.append(br);
        msg.append(br);
        return Pair.of(push, msg.toString());
    }

    private long calcOptCount(FinanceHttpApi.HttpStockData stockData) {
        double atr21 = stockData.getAtr60();
        double closePrice = stockData.getClose().doubleValue();
        double denominator = (atr21 / closePrice * 100) * 10;
        // 计算分子部分：100000 / denominator
        double numerator = 100000.0 / denominator;

        // 再除以closePrice
        double intermediateResult = numerator / closePrice;
        // 向下取整并取100的整数倍
        long result = (long) ((Math.floor(intermediateResult / 100.0)) * 100);
        return result>100?result:100;
    }
}
